package com.txzt.gaea.business.fund.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSONObject;
import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.base.model.DictDetail;
import com.txzt.gaea.base.service.DictInfoService;
import com.txzt.gaea.business.fund.domain.model.FundIssued;
import com.txzt.gaea.business.fund.domain.model.FundIssuedDetail;
import com.txzt.gaea.business.fund.service.IFundIssuedService;
import com.txzt.gaea.business.sequence.service.ISequenceService;
import com.txzt.gaea.business.util.TranslateUtil;
import com.txzt.gaea.common.annotation.EntityCommonValue;
import com.txzt.gaea.common.base.controller.BaseController;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.FundIssuedStatus;
import com.txzt.gaea.upgrade.project.domain.model.ProjectMain;
import com.txzt.gaea.upgrade.project.service.IProjectMainService;
import com.txzt.gaea.vo.AdminUserVO;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/fund/issued")
public class FundIssuedController extends BaseController {

    @Autowired
    private IFundIssuedService iFundIssuedService;
    @Autowired
    private ISequenceService sequenceService;
    @Autowired
    private IProjectMainService iProjectMainService;
    @Autowired
    private DictInfoService dictInfoService;

    /**
     * 分页查询
     * @param pageNumber
     * @param pageSize
     * @param fundIssued
     * @return
     */
    @GetMapping(value = "/list")
    public RtnInfo<?> pageList(@RequestParam(defaultValue = "1") Integer pageNumber,
                               @RequestParam(defaultValue = "10") Integer pageSize, FundIssued fundIssued) {
        if (null != fundIssued.getStartTime()) {
            fundIssued.setStartTime(fundIssued.getStartTime() + " 00:00:00");
        }
        if (null != fundIssued.getEndTime()){
            fundIssued.setEndTime(fundIssued.getEndTime() + " 23:59:59");
        }
        PageQuery<FundIssued> pageList = iFundIssuedService.pageQuery(new PageQuery<>(pageNumber, pageSize, fundIssued));
        pageList.getList().forEach(item -> {
            //翻译部门
            item.setDeptName(TranslateUtil.getDepartmentName(item.getDeptId()));
            //人员名称
            item.setWriteName(TranslateUtil.getUserName(item.getWriteBy()));
            //状态翻译
            item.setStatusName(FundIssuedStatus.getInfoByCode(item.getStatus()));
            //预算科目翻译
            item.setLedgerAccountName(dictInfoService.dictTranslate("ledger_account",item.getLedgerAccount()));
        });
        return RtnInfo.success(pageList);
    }

    /**
     * id查询
     * @param id
     * @return
     */
    @GetMapping(value = "/queryById")
    public RtnInfo<?> queryById(@RequestParam Long id) {
        FundIssued fundIssued = iFundIssuedService.selectById(id);
        if (null == fundIssued) {
            return RtnInfo.SERVER_ERROR;
        }else {
            //项目名称
            ProjectMain projectInfo = iProjectMainService.selectById(fundIssued.getProjectId());
            fundIssued.setProjectName(projectInfo.getProjectName());
            fundIssued.setProjectNo(projectInfo.getPlanNo());
            return RtnInfo.success(fundIssued);
        }
    }

    private String createApplyNo(){
        Calendar calendar = Calendar.getInstance();
        // 获取当前年
        int year = calendar.get(Calendar.YEAR);
        Integer sequence = sequenceService.getSequence("fund_issued", "apply_no");
        return year + "JFXD" + String.format("%03d", sequence);
    }

    /**
     * 新增
     * @param fundIssued
     * @return
     */
    @PostMapping(value = "/add")
    @EntityCommonValue(operation = "CREATE")
    public RtnInfo<?> add(@RequestBody FundIssued fundIssued) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        fundIssued.setStatus(FundIssuedStatus.SUBMIT.getCode());
        fundIssued.setWriteBy(adminUserVO.getId());
        fundIssued.setDeptId(adminUserVO.getDeptid());
        fundIssued.setWriteTime(new Date());
        fundIssued.setApplyNo(createApplyNo());
        int count = iFundIssuedService.add(fundIssued);
        if (count == 99) {
            return RtnInfo.error(99,"存在重复项目，请检查");
        }
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 保存
     * @param fundIssued
     * @return
     */
    @PostMapping(value = "/save")
    @EntityCommonValue(operation = "CREATE")
    public RtnInfo<?> save(@RequestBody FundIssued fundIssued) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        fundIssued.setStatus(FundIssuedStatus.UN_SUBMIT.getCode());
        fundIssued.setWriteBy(adminUserVO.getId());
        fundIssued.setDeptId(adminUserVO.getDeptid());
        fundIssued.setWriteTime(new Date());
        fundIssued.setApplyNo(createApplyNo());
        int count = iFundIssuedService.add(fundIssued);
        if (count == 99) {
            return RtnInfo.error(99,"存在重复项目，请检查");
        }
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 修改
     * @param fundIssued
     * @return
     */
    @PostMapping(value = "/edit")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> edit(@RequestBody FundIssued fundIssued) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        fundIssued.setStatus(FundIssuedStatus.SUBMIT.getCode());
        fundIssued.setWriteBy(adminUserVO.getId());
        fundIssued.setDeptId(adminUserVO.getDeptid());
        fundIssued.setWriteTime(new Date());
        int count = iFundIssuedService.updateById(fundIssued);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }

    /**
     * 经费到账
     * @param fundIssued
     * @return
     */
    @PostMapping(value = "/arrived")
    @EntityCommonValue(operation = "UPDATE")
    public RtnInfo<?> arrived(@RequestBody FundIssued fundIssued) {
        Date now = new Date(); // 创建一个Date对象，获取当前时间
        // 指定格式化格式
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        fundIssued.setStatus(FundIssuedStatus.SUBMIT.getCode());
        fundIssued.setWriteTime(now);
        FundIssued orgFundIssued = iFundIssuedService.selectById(fundIssued.getId());
        List<FundIssuedDetail> logList = JSONObject.parseArray(orgFundIssued.getArriveDetail(), FundIssuedDetail.class);
        FundIssuedDetail map = new FundIssuedDetail();
        map.setDate(f.format(now));
        map.setValue(fundIssued.getFundReceive());
        if (null == logList){
            logList = new ArrayList<>();
        }
        logList.add(map);
        fundIssued.setArriveDetail(JSONObject.toJSONString(logList));
        fundIssued.setFundReceive(fundIssued.getFundReceive().add(orgFundIssued.getFundReceive()));
        int count = iFundIssuedService.updateById(fundIssued);
        if (count > 0) {
            return RtnInfo.SUCCESS;
        } else {
            return RtnInfo.SERVER_ERROR;
        }
    }



    /**
     * 导入模板下载
     */
    @GetMapping(value = "/import/temp")
    public void importTemp(HttpServletResponse response) throws IOException {
        List<FundIssued> fundIssuedList = new ArrayList<>();
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("导入模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        Set<String> excludeColumnFiledNames = new HashSet<>();
        excludeColumnFiledNames.add("statusName");
        excludeColumnFiledNames.add("applyNo");
        excludeColumnFiledNames.add("writeName");
        excludeColumnFiledNames.add("deptName");
        excludeColumnFiledNames.add("writeTime");
        EasyExcel.write(response.getOutputStream(), FundIssued.class)
                .excludeColumnFieldNames(excludeColumnFiledNames)
                .sheet("导入模板")
                .doWrite(fundIssuedList);
    }

    /**
     * 导出
     */
    @GetMapping(value = "/export")
    public void exportExcel(HttpServletResponse response,@RequestParam(defaultValue = "1") Integer pageNumber,
                            @RequestParam(defaultValue = "10") Integer pageSize, FundIssued fundIssued) throws IOException {
        PageQuery<FundIssued> pageList = iFundIssuedService.pageQuery(new PageQuery<>(pageNumber, pageSize, fundIssued));
        pageList.getList().forEach(item -> {
            //翻译部门
            item.setDeptName(TranslateUtil.getDepartmentName(item.getDeptId()));
            //人员名称
            item.setWriteName(TranslateUtil.getUserName(item.getWriteBy()));
            //状态翻译
            item.setStatusName(FundIssuedStatus.getInfoByCode(item.getStatus()));
            //预算科目翻译
            item.setLedgerAccountName(dictInfoService.dictTranslate("ledger_account",item.getLedgerAccount()));
        });
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("经费下达数据导出", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), FundIssued.class)
                .sheet("数据列表")
                .doWrite(pageList.getList());
    }

    /**
     * 导入
     */
    @PostMapping("/import")
    @ResponseBody
    public RtnInfo<?> importExcel(MultipartFile file) throws IOException {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        List<FundIssued> fundIssuedList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), FundIssued.class,
                new PageReadListener<FundIssued>(fundIssuedList::addAll)).sheet().doRead();
        int index = 0;
        if (0 == fundIssuedList.size()){
            return RtnInfo.error(99,"无数据，无法导入");
        }
        for (FundIssued fundIssued : fundIssuedList){
            index++;
            fundIssued.setWriteBy(adminUserVO.getId());
            fundIssued.setDeptId(adminUserVO.getDeptid());
            fundIssued.setWriteTime(new Date());
            fundIssued.setStatus(FundIssuedStatus.UN_SUBMIT.getCode());
            //查找项目ID
            if(null != fundIssued.getProjectNo()){
                ProjectMain projectInfo = iProjectMainService.selectProjectByPlanNo(fundIssued.getProjectNo());
                if (null != projectInfo){
                    //查看重复提交
                    FundIssued queryParam = new FundIssued();
//                    queryParam.setProjectNo(fundIssued.getProjectNo());
                    queryParam.setProjectId(projectInfo.getId());
                    FundIssued org = iFundIssuedService.selectOne(queryParam);
//                    if (null != org){
//                        return RtnInfo.error(99,"该项目已提交经费下达，请检查计划编号为 "+ fundIssued.getProjectNo() +" 的数据");
//                    }
                    if (null != org) {
                        fundIssued.setId(org.getId());
                        fundIssued.setStatus(org.getStatus());
                    }
                    fundIssued.setProjectId(projectInfo.getId());
                    fundIssued.setPlanBudget(projectInfo.getBudgetFund());
                }else {
                    return RtnInfo.error(99,"未找到项目，请检查计划编号为 "+ fundIssued.getProjectNo() +" 的数据");
                }
            }else {
                return RtnInfo.error(99,"计划编号不能为空，请检查第 "+ (index+1) +" 行数据");
            }
            //预算科目
            if (null != fundIssued.getLedgerAccountName()){
                String dictValue = dictInfoService.getDictValue("ledger_account",fundIssued.getLedgerAccountName());
                if (null != dictValue){
                    fundIssued.setLedgerAccount(dictValue);
                }else{
                    return RtnInfo.error(99,"未找到预算科目对应数据字典，请检查第 "+ (index+1) +" 行数据");
                }
            }else {
                return RtnInfo.error(99,"预算科目不能为空，请检查第 "+ (index+1) +" 行数据");
            }
            //能力建设体系 级联查询
            if (null != fundIssued.getCapacityBuildingOneName()){
                DictDetail dictDetail = dictInfoService.
                        selectDictValue("capacity_building",fundIssued.getCapacityBuildingOneName());
                if (null != dictDetail){
                    fundIssued.setCapacityBuildingOne(dictDetail.getValue());
                    if (null != fundIssued.getCapacityBuildingTwoName()){
                        DictDetail dictDetailTwo = dictInfoService.
                                getSubDictValue(dictDetail.getSubDictId(),fundIssued.getCapacityBuildingTwoName());
                        if (null != dictDetailTwo){
                            fundIssued.setCapacityBuildingTwo(dictDetailTwo.getValue());
                            if (null != fundIssued.getCapacityBuildingThreeName()){
                                DictDetail dictDetailThree = dictInfoService.
                                        getSubDictValue(dictDetailTwo.getSubDictId(),
                                                fundIssued.getCapacityBuildingThreeName());
                                if (null != dictDetailThree){
                                    fundIssued.setCapacityBuildingThree(dictDetailThree.getValue());
                                }
                            }
                        }else{
                            fundIssued.setCapacityBuildingTwoName(null);
                            fundIssued.setCapacityBuildingThreeName(null);
                        }
                    }else{
                        fundIssued.setCapacityBuildingThreeName(null);
                    }
                }else{
                    fundIssued.setCapacityBuildingOneName(null);
                    fundIssued.setCapacityBuildingTwoName(null);
                    fundIssued.setCapacityBuildingThreeName(null);
                }
            }else {
                fundIssued.setCapacityBuildingTwoName(null);
                fundIssued.setCapacityBuildingThreeName(null);
            }
            //编号生成
            if (fundIssued.getId()==null){
                //仅新增数据时生成编号
                fundIssued.setApplyNo(createApplyNo());
            }
        }
        //存数据
        //新增数据
        List<FundIssued> addList = new ArrayList<>();
        //List<FundIssued> updateList = new ArrayList<>();
        for (FundIssued issued : fundIssuedList) {
            if (issued.getId()!=null){
                iFundIssuedService.updateById(issued);
            }else {
                addList.add(issued);
            }
        }
        if (addList.size()>0){
            iFundIssuedService.insertBatch(FundIssued.class,addList);
        }
        return RtnInfo.SUCCESS;
    }


}
